package cn.edu.ujs.coor.service;

import cn.edu.ujs.coor.common.exception.CoorException;
import cn.edu.ujs.coor.model.Access;
import cn.edu.ujs.coor.model.Role;
import cn.edu.ujs.coor.repository.relation.AccessRepository;
import cn.edu.ujs.coor.repository.relation.RoleUserRelationRepository;
import cn.edu.ujs.coor.repository.role.RoleRepository;
import cn.edu.ujs.coor.request.IdRequest;
import cn.edu.ujs.coor.request.role.RoleAddRequest;
import cn.edu.ujs.coor.request.role.RoleConfig;
import cn.edu.ujs.coor.request.role.RoleConfigRequest;
import cn.edu.ujs.coor.request.role.RoleUpdateRequest;
import cn.edu.ujs.coor.util.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional(rollbackFor = Exception.class)
public class RoleService extends BaseService<Role, Role> {

    @Autowired
    private RoleUserRelationRepository roleUserRelationRepository;

    @Autowired
    private AccessRepository accessRepository;

    @Autowired
    public void setRepository (RoleRepository repository) {
        this.repository = repository;
    }

    public List<Role> list () {
        List<Role> list = findAll();
        for (Role role : list) {
            role.setNodeIds(((RoleRepository) repository).findNodeByRoleId(role.getId()));
        }
        return list;
    }

    public void save (RoleAddRequest request) {
        Role role = Role.builder().build();
        BeanUtil.copyBeanIgnoreNull(role, request);
        this.save(role);
        if (request.getNodeIds() != null) {
            for (String nodeId : request.getNodeIds()) {
                Access access = Access.builder().roleId(role.getId()).nodeId(nodeId).build();
                accessRepository.save(access);
            }
        }
    }

    /**
     * 更新角色
     * @param request
     */
    public void update (RoleUpdateRequest request) {
        Role role = this.findById(request.getId());
        if (role == null) {
            throw new CoorException("er_000002", "该角色不存在");
        }
        BeanUtil.copyBeanIgnoreNull(role, request);
        this.save(role);
        // 更新角色权限关联
        accessRepository.deleteByRoleId(role.getId());
        if (request.getNodeIds() != null) {
            for (String nodeId : request.getNodeIds()) {
                Access access = Access.builder().roleId(role.getId()).nodeId(nodeId).build();
                accessRepository.save(access);
            }
        }
    }

    /**
     * 删除角色
     * @param request
     */
    public void delete (IdRequest request) {
        Role role = this.findById(request.getId());
        if (role == null) {
            throw new CoorException("er_000002", "该角色不存在");
        }
        // 删除角色关联
        roleUserRelationRepository.deleteByRoleId(role.getId());
        accessRepository.deleteByRoleId(role.getId());
        // 删除角色记录
        this.delete(role);
    }

    /**
     * 配置角色权限
     * @param request
     */
    public void config (RoleConfigRequest request) {
        Role role = this.findById(request.getId());
        if (role == null) {
            throw new CoorException("er_000002", "该角色不存在");
        }
        // 删除原有关联
        accessRepository.deleteByRoleId(request.getId());
        // 设置新的关联
        if (request.getConfigs() != null && request.getConfigs().size() > 0) {
            for (RoleConfig config : request.getConfigs()) {
                Access access = Access
                        .builder()
                        .roleId(request.getId())
                        .nodeId(config.getNodeId())
                        .operation(config.getOperation())
                        .build();
                accessRepository.save(access);
            }
        }
    }
}
